package com.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * 程序的入口，负责启动应用
 * @author liuyazhuang
 *
 */
public class Main {
	public static void main(String[] args) {
		//NioEventLoopGroup用来处理I/O操作的多线程事件循环器
		EventLoopGroup bossGroup = new NioEventLoopGroup();//用来接收进来的连接
		EventLoopGroup workGroup = new NioEventLoopGroup();//用来处理已经被接收的连接
		/*一旦‘boss’接收到连接，就会把连接信息注册到‘worker’上。如何知道多少个线程已经被使用，
		如何映射到已经创建的 Channel上都需要依赖于 EventLoopGroup 的实现，并且可以通过构造函数来配置他们的关系。*/
		try {
			ServerBootstrap b = new ServerBootstrap();//ServerBootstrap是一个启动 NIO 服务的辅助启动类
			b.group(bossGroup, workGroup);
			b.channel(NioServerSocketChannel.class);
			//b.childHandler(new MyWebSocketChannelHandler());//MyWebSocketChannelHandler 继承自ChannelInitializer是一个特殊的处理类，他的目的是帮助使用者配置一个新的 Channel
			b.option(ChannelOption.SO_BACKLOG, 128);        //.option() 是提供给NioServerSocketChannel用来接收进来的连接  
            b.childOption(ChannelOption.SO_KEEPALIVE, true);//childOption() 是提供给由父管道ServerChannel接收到的连接，在这个例子中也是 NioServerSocketChannel。
			System.out.println("服务端开启等待客户端连接....");
			Channel ch = b.bind(9090).sync().channel();// 绑定端口，开始接收进来的连接
			ch.closeFuture().sync();
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//优雅的退出程序
			bossGroup.shutdownGracefully();
			workGroup.shutdownGracefully();
		}
	}
}
